Cloud FunctionsからAmazon SNSを使ってメールを送信する
データアナリティクス事業本部の鈴木です。
Google Cloud Platform上でイベントが起きた際に、メールを送りたいケースがありました。
このようなときのための構成で、Amazon SESと連携する例は以下の記事で紹介されていますが、私はSESよりAmazon SNSをよく使うので、この記事を参考に、SNSを使った例を試してみました。
構成
以下のような構成としました。
Cloud FunctionsでPythonからboto3を使い、Amazon SNSのAPIを呼び出すような作りにしています。Cloud Functionsの起動は、簡単にコンソールのテスト機能で呼び出すことを想定しています。
やってみた
SNSトピックの作成(AWS側)
CloudFormationテンプレートを使って、SNSトピックを作成しました。
AWSTemplateFormatVersion: 2010-09-09 Description: sample sns Parameters: SNSTopicName: Description: SNSTopicName for Alarm Type: String Default: sample-topic NotificationTarget: Description: Email for notification Type: String Resources: ## SNSトピック SnsTopic: Type: AWS::SNS::Topic Properties: TopicName: !Ref SNSTopicName Subscription: - Endpoint: !Ref NotificationTarget Protocol: email
例えばこのようにスタックを作っておきました。
通知先のメールアドレス
の箇所に入力したメールアドレスにサブスクリプションの承諾依頼が届くので、承諾しておきました。
クレデンシャルの準備(AWS側)
AWS SDK for Python を使用して Amazon SNS 経由でメールを送信するため、SNSをキックするためのIAMユーザーを作成し、AWS アクセスキー ID
とAWS シークレットアクセスキー
を用意しました。
以下のように、sns:Publish
のみ許可したポリシーを別途作成し、ユーザー作成時にアタッチしておきました。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "SNSPublish", "Effect": "Allow", "Action": "sns:Publish", "Resource": "*" } ] }
今回はアクセスキーなどを払い出してGoogle Cloud側に渡してしまうので、SNSトピックのARNが分かっている場合は、Resource
で指定して権限を絞っておくとより良いです。
作成したIAMユーザーの認証情報タブなどから、アクセスキーを作成してダウンロードしておきました。アクセスキーの作成方法については以下を参照ください。
関数の作成(Google Cloud側)
Cloud Functionsから通知用の関数を作成します。まず、Cloud Functionsのコンソールに移動し、関数を作成
を押しました。
次の画面で、構成を入力していきます。基本は以下のように入力しました。トリガーはHTTPを選択して保存しておきました。
Runtime, build, connections and security setting
を開くと、ランタイム環境変数を入力する箇所があるので、以下のように記入しました。特に赤字の箇所は、AWS側で作成したリソースに合わせて入力しました。
コードの画面では、実行するプログラムの設定を行いました。今回は以下のように入力しました。
まず設定は以下としました。
- ランタイム: Python 3.9
- エントリーポイント: send_email
またコードは以下のものを入力しました。
import os import boto3 def send_email(request): # 引数取得 request_json = request.get_json() subject = request_json['subject'] # メールタイトル message = request_json['message'] # メール本文 # 環境変数取得 AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY_ID = os.getenv('AWS_SECRET_ACCESS_KEY_ID') TOPIC_ARN = os.getenv('TOPIC_ARN') # SNSクライアント client = boto3.client( 'sns', aws_access_key_id=AWS_ACCESS_KEY_ID, # アクセスキー aws_secret_access_key=AWS_SECRET_ACCESS_KEY_ID, # シークレットキー region_name='ap-northeast-1' ) # メールの内容作成 sns_request = { 'TopicArn': TOPIC_ARN, 'Message': message, 'Subject': subject } # メール送信 response = client.publish(**sns_request) print(response) return "OK"
アクセスキーなどのクレデンシャル情報は、環境変数から渡すこととしました。
boto3のインストールは、requirements.txt
に記載することでできました。以下のように記載しました。
boto3>=1.17.100
入力後は、問題なかったので、左下のデプロイ
ボタンを押してデプロイしました。
しばらくして、関数が作成されたことを確認できました。
テストメールの送信
関数が作成されたので、早速SNSとの疎通を確認しました。関数の名前をクリックして、テスト中
タブを押しました。
するとトリガーとなるイベントを入力できるので、以下のように入力してテストを実行しました。
{ "subject" : "テストメール", "message" : "Cloud Functions からSNS経由のメールです。" }
SNSトピックで設定したメールアドレスで届いたメールを確認すると、確かにメールが受信できました。
最後に
今回はCloud FunctionsからAmazon SNSを使ってメールを送る方法をご紹介しました。参考になりましたら幸いです。